local Piece = require "packages.chess-games.nchess.core.piece"

local Rook = require "packages.chess-games.nchess.core.pieces.rook"
local Knight = require "packages.chess-games.nchess.core.pieces.knight"
local Bishop = require "packages.chess-games.nchess.core.pieces.bishop"
local Queen= require "packages.chess-games.nchess.core.pieces.queen"
local King   = require "packages.chess-games.nchess.core.pieces.king"
local Pawn   = require "packages.chess-games.nchess.core.pieces.pawn"

---@class NChess.Engine : Base.Engine
---@field public pieces table<integer, NChess.Piece>
local Engine = Fk.Base.Engine:subclass("NChess.Engine")

-- 全是写死棋子坐标和id的，过于繁冗，折叠起来
do -- Please give me a piece of pie.

  Engine.rook = Rook
  Engine.knight = Knight
  Engine.bishop = Bishop
  Engine.queen = Queen
  Engine.king = King
  Engine.pawn = Pawn

  -- 红方
  Engine.wR1 =  1
  Engine.wN1 =  2
  Engine.wB1 =  3
  Engine.wQ  =  4
  Engine.wK  =  5
  Engine.wB2 =  6
  Engine.wN2 =  7
  Engine.wR2 =  8
  Engine.wP1 =  9
  Engine.wP2 = 10
  Engine.wP3 = 11
  Engine.wP4 = 12
  Engine.wP5 = 13
  Engine.wP6 = 14
  Engine.wP7 = 15
  Engine.wP8 = 16

  -- 黑方
  Engine.bR1 =  -1
  Engine.bN1 =  -2
  Engine.bB1 =  -3
  Engine.bQ  =  -4
  Engine.bK  =  -5
  Engine.bB2 =  -6
  Engine.bN2 =  -7
  Engine.bR2 =  -8
  Engine.bP1 =  -9
  Engine.bP2 = -10
  Engine.bP3 = -11
  Engine.bP4 = -12
  Engine.bP5 = -13
  Engine.bP6 = -14
  Engine.bP7 = -15
  Engine.bP8 = -16

  -- Engine 内部记录每颗棋子的初始坐标
  Engine.initialPositions = {
    -- 红方
    [Engine.wR1] = {x=1, y=8},
    [Engine.wN1] = {x=2, y=8},
    [Engine.wB1] = {x=3, y=8},
    [Engine.wQ ] = {x=4, y=8},
    [Engine.wK ] = {x=5, y=8},
    [Engine.wB2] = {x=6, y=8},
    [Engine.wN2] = {x=7, y=8},
    [Engine.wR2] = {x=8, y=8},
    [Engine.wP1] = {x=1, y=7},
    [Engine.wP2] = {x=2, y=7},
    [Engine.wP3] = {x=3, y=7},
    [Engine.wP4] = {x=4, y=7},
    [Engine.wP5] = {x=5, y=7},
    [Engine.wP6] = {x=6, y=7},
    [Engine.wP7] = {x=7, y=7},
    [Engine.wP8] = {x=8, y=7},

    -- 黑方
    [Engine.bR1] = {x=1, y=1},
    [Engine.bN1] = {x=2, y=1},
    [Engine.bB1] = {x=3, y=1},
    [Engine.bQ ] = {x=4, y=1},
    [Engine.bK ] = {x=5, y=1},
    [Engine.bB2] = {x=6, y=1},
    [Engine.bN2] = {x=7, y=1},
    [Engine.bR2] = {x=8, y=1},
    [Engine.bP1] = {x=1, y=2},
    [Engine.bP2] = {x=2, y=2},
    [Engine.bP3] = {x=3, y=2},
    [Engine.bP4] = {x=4, y=2},
    [Engine.bP5] = {x=5, y=2},
    [Engine.bP6] = {x=6, y=2},
    [Engine.bP7] = {x=7, y=2},
    [Engine.bP8] = {x=8, y=2},
  }

  Engine.piecePENCodeList = {
    ["white"] = {
      ["rook"] = "R",
      ["knight"] = "N",
      ["bishop"] = "B",
      ["queen"] = "Q",
      ["king"] = "K",
      ["pawn"] = "P",
    },

    ["black"] = {
      ["rook"] = "r",
      ["knight"] = "n",
      ["bishop"] = "b",
      ["queen"] = "q",
      ["king"] = "k",
      ["pawn"] = "p",
    },
  }

  Engine.ChineseNumbers = {"一", "二", "三", "四", "五", "六", "七", "八"}
  Engine.ArabicNumbers = {"１", "２", "３", "４", "５", "６", "７", "８"}
  Engine.AlphabetNumbers = {"a", "b", "c", "d", "e", "f", "g", "h"}
end

function Engine:initialize()
  Fk.Base.Engine.initialize(self)

  self.pieces = {}
end

function Engine:addPiece(piece)
  self.pieces[piece.id] = piece
end

---@param id integer
---@return NChess.Piece
function Engine:getPieceById(id)
  local piece = self.pieces[id]
  if Fk:currentRoom().extra_pieces and Fk:currentRoom().extra_pieces[id] then
    piece = Fk:currentRoom().extra_pieces[id]
  end
  return piece
end

---@return integer[][]
function Engine:createBoard()
  -- 创建空棋盘
  local board = {
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},

    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
  }

  -- 遍历32颗棋子，根据 initialPositions 写回初始坐标
  for id, pos in pairs(self.initialPositions) do
    board[pos.y][pos.x] = id
  end

  return board
end

function Engine:getLineNumber(x, color)
  if color == "white" then
    return self.ChineseNumbers[10 - x]
  else
    return self.ArabicNumbers[x]
  end
end

function Engine:translateMovement(pieceId, board, fromX, fromY, x, y, eatMark, move)
  local _rule = ""
  if eatMark then
    _rule = _rule .. " X "
  end
  if move.type == "promotion" then
    local p = self:getPieceById(board[y][x])
    _rule = _rule .. "升变-" .. p.whiteStr
  elseif move.type == "castling" then
    _rule = _rule .. (x == 3 and "长易位" or "短易位")
  elseif move.type == "en_passant" then
    _rule = _rule .. " X "
  end
  local fromPos = self.AlphabetNumbers[fromX] .. self.ArabicNumbers[9 - fromY]
  local toPos = self.AlphabetNumbers[x] .. self.ArabicNumbers[9 - y]
  return { self:getPieceById(pieceId).whiteStr, fromPos, toPos, "<font color='#483D8B'>" .. _rule .. "</font>"}
end

---@param name string
---@param color string
---@return NChess.Piece
function Engine:clonePiece(name, color)
  local piece = Piece:clone(name, Engine[name])
  return piece
end

function Engine:isChecking(board, color)
  for Y, arrX in ipairs(board) do
    for X, id in ipairs(arrX) do
      if (id > 0 and color == "white") or (id < 0 and color == "black") then
        local kingId = id > 0 and self.bK or self.wK
        local kingX, kingY
        for _y, xArr in ipairs(board) do
          for _x, _id in ipairs(xArr) do
            if _id == kingId then
              kingX = _x
              kingY = _y
              break
            end
          end
          if kingX then break end
        end
        if self:getPieceById(id):canMoveTo(board, X, Y, kingX, kingY) then
          return true
        end
      end
    end
  end
end

---测试用
---@param board table
function Engine:printBoard(board)
  print("---------------------------------------")
  for _, arr in ipairs(board) do
    p(table.map(arr, function (n)
      local spaces = 2
      if n < 0 then spaces = spaces - 1 end
      if math.abs(n) > 9 then spaces = spaces - 1 end
      local list = { "", " ", "  " }
      return list[spaces + 1] .. tostring(n)
    end))
  end
  print("---------------------------------------")
end

return Engine
